/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.implementation.representation;

import java.io.StringWriter;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import main.framework.exception.RepresentationCreationException;
import main.framework.http.ContentType;
import main.framework.http.MessageBody;
import main.framework.representation.RepresentationCreator;
import main.framework.resource.Resource;
import main.framework.resource.ResourceData;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * This class represents a representation creator for the XML content type.
 */
public class XMLRepresentationCreator extends RepresentationCreator {

	/**
	 * Creates a representation creator for the XML content type.
	 * 
	 * @param contentType The desired content type for the representations to be created by the representation creator.
	 */
	public XMLRepresentationCreator(ContentType contentType) {
		super(contentType);
	}
	
	@Override
	public MessageBody createRepresentation(String data) throws RepresentationCreationException {
		try {
			// build document
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  
	        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
	        Document document = documentBuilder.newDocument();
	        Element rootElement = document.createElement("xml");
	        rootElement.setTextContent(data);
	        document.appendChild(rootElement);
	        // create a transformer object to write the xml document to a file or a string
	        Transformer transformer = TransformerFactory.newInstance().newTransformer();
	        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
	        // initialize StreamResult with File object to save to file
	        StreamResult result = new StreamResult(new StringWriter());
	        DOMSource source = new DOMSource(document);
	        transformer.transform(source, result);
	        String representationString = result.getWriter().toString();
			return new MessageBody(representationString, super.contentType);
		} catch (Exception e) {
			throw new RepresentationCreationException(e.getMessage());
		}
	}

	@Override
	public MessageBody createRepresentation(ResourceData resourceData) throws RepresentationCreationException {
		try {
			String uriNode = resourceData.getResource().getURINode().getUriNode();
	        List<Resource> childrenResources = resourceData.getResource().getChildren();
			// build document
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();  
	        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
	        Document document = documentBuilder.newDocument();
	        Element rootElement = document.createElement(uriNode);
	        rootElement.setAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink");
	        // return a list of all children if they exist, else return the value
	    	for (int i = 0; i < resourceData.getData().size(); i++) {
				for (int j = 0; j < resourceData.getData().get(i).length; j++){
					Element childElement;
					if(childrenResources.size() == 0){
						// last node --> data comes from SQL query, first row are the column names
						if (i > 0){
							childElement = document.createElement(resourceData.getData().get(0)[j]);
			    			childElement.setTextContent(resourceData.getData().get(i)[j]);
							rootElement.appendChild(childElement);
						}
					} else {
						childElement = document.createElement(childrenResources.get(i).getURINode().getUriNode());
		    			childElement.setAttribute("xlink:href", childrenResources.get(i).getResourceURI().getResourceUri());
						rootElement.appendChild(childElement);
					}
				}
			}
	        document.appendChild(rootElement);
	        // create a transformer object to write the xml document to a file or a string
	        Transformer transformer = TransformerFactory.newInstance().newTransformer();
	        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
	        // initialize StreamResult with File object to save to file
	        StreamResult result = new StreamResult(new StringWriter());
	        DOMSource source = new DOMSource(document);
	        transformer.transform(source, result);
	        String representationString = result.getWriter().toString();
			MessageBody messageBody = new MessageBody(representationString, super.contentType);
			return messageBody;
		} catch (Exception e) {
			throw new RepresentationCreationException(e.getMessage());
		}
	}
	
}
